package com.xmmxjy.system.aop;

import com.alibaba.fastjson.JSONObject;
import com.xmmxjy.common.service.ProducerService;
import com.xmmxjy.common.util.*;
import com.xmmxjy.system.entity.LogEntity;
import com.xmmxjy.system.shiro.ShiroSessionUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Date;


/**
 * Created by xmm on 2017/3/9.
 * aop日志处理类
 */
@Aspect
@Component
public class LogAspect {

    private static Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Autowired
    private ProducerService producerService;
    /**
     * 切面 doAdd doEdit doDelete
     */
    @Pointcut("execution(* com.xmmxjy.system.controller.*.do*(..))")
    public void logPoint() {

    }

    /**
     * list 方法切面
     */
    @Pointcut("execution(* com.xmmxjy.system.controller.*.list(..))")
    public void logPointList() {

    }

    /**
     * 对注解进行切面
     */
    @Pointcut("@annotation(com.xmmxjy.system.aop.LogAnnotation)")
    public void logger() {

    }
    /**
     * 在方法之前执行
     * @param point
     */
    @Before("logPoint()")
    public void doBefore(JoinPoint point) {
        //参数
        Object[] obj = point.getArgs();
        //方法
        String methods = point.getSignature().getDeclaringTypeName() +
                "." + point.getSignature().getName();
        System.out.println("before");

    }

    /**
     * 返回后增强 list
     * @param point
     * @param returnValue
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
  /*  @AfterReturning(pointcut = "logPointList()", returning="returnValue")
    public void afterReturningList(JoinPoint point, AjaxJson returnValue) throws NoSuchFieldException, IllegalAccessException {
        String methodName = point.getSignature().getName();
        LogEntity log = new LogEntity();
        Object [] objects = point.getArgs();
        Object o = null;
        if (objects != null && objects.length > 0) {
            o = objects[0];
        }
        log.setLogContent("查询参数：" + BeanUtil.beanToString(o));
        //获取IP
        log.setOperateIp(Tools.getRemoteHost(ContextHolderUtils.getRequest()));
        log.setOperateTime(new Date());
        log.setUserId(ShiroSessionUtils.getLoginUser().getId());
        log.setOperateType(methodName);
        String module = (String) ReflectHelper.getValueByFieldName(point.getTarget(),"CURRENT_PAGE");
        if (Tools.notEmpty(module)) {
            log.setOperateModule(module.substring(0,module.length()));
        }
        logger.info(log.toString());
        //给队列里面发送消息
        producerService.sendObjectMessage(log);
    }*/

    /**
     *返回后增强 add edit delete
     */
    @AfterReturning(pointcut = "logPoint()", returning="returnValue")
    public void afterReturning(JoinPoint point, AjaxJson returnValue) throws NoSuchFieldException, IllegalAccessException {
        /*System.out.println("@AfterReturning：目标方法为：" +
                point.getSignature().getDeclaringTypeName() +
                "." + point.getSignature().getName());
        System.out.println("@AfterReturning：目标方法为："  + point.getSignature().getName());
        System.out.println("@AfterReturning：参数为：" +
                Arrays.toString(point.getArgs()));
        System.out.println("@AfterReturning：返回值为：" + returnValue);
        System.out.println(returnValue.isSuccess());
        System.out.println(point.getTarget());
        System.out.println("@AfterReturning：被织入的目标对象为：" + point.getTarget());*/
        String methodName = point.getSignature().getName();
        LogEntity log = new LogEntity();
        Object [] objects = point.getArgs();
        Object o = null;
        if (objects != null && objects.length > 0) {
            o = objects[0];
        }
        log.setLogContent( "操作对象： "+ BeanUtil.beanToString(o) + "操作信息：" + returnValue.getMsg());
        //获取IP
        log.setOperateIp(Tools.getRemoteHost(ContextHolderUtils.getRequest()));
        log.setOperateTime(new Date());
        log.setUserId(ShiroSessionUtils.getLoginUser().getId());
        log.setOperateType(methodName);
        log.setLogLevel("info");
        String module = (String) ReflectHelper.getValueByFieldName(point.getTarget(),"CURRENT_PAGE");
        if (Tools.notEmpty(module)) {
            log.setOperateModule(module.substring(0,module.length() -1));
        }
        log.setOperateStatus(returnValue.isSuccess() ? "1" : "0");
        logger.info(log.toString());
        //给队列里面发送消息
        producerService.sendObjectMessage(log);
    }


    @Around("logPoint()")
    public Object doAround(ProceedingJoinPoint point) throws Throwable {

        return point.proceed();
    }
    @Around("logPointList()")
    public Object doAround2(ProceedingJoinPoint point) throws Throwable {
        String methodName = point.getSignature().getName();
        LogEntity log = new LogEntity();
        Object [] objects = point.getArgs();
        Object o = null;
        if (objects != null && objects.length > 0) {
            o = objects[0];
        }
        //log.setLogContent("查询参数：" + BeanUtil.beanToString(o));
        //获取IP
        log.setOperateIp(Tools.getRemoteHost(ContextHolderUtils.getRequest()));
        log.setOperateTime(new Date());
        log.setUserId(ShiroSessionUtils.getLoginUser().getId());
        log.setOperateType(methodName);
        String module = (String) ReflectHelper.getValueByFieldName(point.getTarget(),"CURRENT_PAGE");
        if (Tools.notEmpty(module)) {
            log.setOperateModule(module.substring(0,module.length() - 1));
        }
        log.setLogLevel("info");
        logger.info(log.toString());
        //给队列里面发送消息
        producerService.sendObjectMessage(log);
        return point.proceed();
    }
    @Around("logger()")
    public Object doAroundLogger(ProceedingJoinPoint point) throws Throwable {
        String methodName = point.getSignature().getName();
        LogEntity log = new LogEntity();
        Object [] objects = point.getArgs();
        Object o = null;
        if (objects != null && objects.length > 0) {
            o = objects[0];
        }
        //log.setLogContent("查询参数：" + BeanUtil.beanToString(o));
        //获取IP
        log.setOperateIp(Tools.getRemoteHost(ContextHolderUtils.getRequest()));
        MethodSignature ms = (MethodSignature) point.getSignature();
        Method method = ms.getMethod();
        LogAnnotation annotationLogger = method.getAnnotation(LogAnnotation.class);
        String eventType = annotationLogger.eventType();
        String operateType = annotationLogger.operateType();
        String operateModule = annotationLogger.operateModule();
        log.setOperateTime(new Date());
        log.setUserId(ShiroSessionUtils.getLoginUser().getId());
        log.setOperateType(operateType);
        log.setOperateModule(operateModule);
        // 1代表业务，0代表系统
        log.setEventType("1");
        log.setLogLevel("info");
        //1代表成功
        log.setOperateStatus("1");
        logger.info(log.toString());
        //给队列里面发送消息
        producerService.sendObjectMessage(log);
        return point.proceed();
    }
}
